import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;


public class SystemCatologReport2 {
	public RandomAccessFile raf; 
	public SystemCatologReport2(String input) throws IOException{
		raf = new RandomAccessFile(input, "rw");
	}
	public int size() throws IOException{
		return (int) raf.length();
	}
	public void createAPage() throws IOException{
		int pageNumber = this.pageNumber();
		int offset = (pageNumber-1)*512;
		raf.seek(offset);
		raf.write(0);
		offset += 512;
		raf.seek(offset);
		raf.write(1);
		offset += 31;
		raf.seek(offset);
		raf.write(2);
	}
	public void createAPage2() throws IOException{
		if(raf.length()==0){
			raf.write(1);
			raf.seek(31);
			raf.write(2);
		}
		else{
			boolean status = false;
			int offset=0;
			while(!status){
				raf.seek(offset);
				status = raf.readBoolean();
				if(status){
					raf.seek(offset);
					raf.write(0);
					raf.seek(offset+512);
					raf.write(1);
					raf.seek(offset+512+31);
					raf.write(2);
					status=true;
				}else{
					offset +=512;
				}			
			}
		}
	}
	public int pageNumber() throws IOException{
		return (int) (raf.length()/512+1);
	}
	public int findPageNumber(String s) throws IOException{
		int page=0;
		boolean pageFound = false;
		raf.seek(0);
		boolean status = false;
		String pageHeader;
		while(!status && !pageFound){
			pageHeader = "";
			raf.seek(page*512);
			status = raf.readBoolean();
			for(int i=0; i<26; i++){
				pageHeader += (char) raf.readByte();
			}
			page++;
			if(pageHeader.compareToIgnoreCase(s)>=0){
				pageFound = true;
			}
		}
		if(!pageFound){
			page = -1;
		}
		return page;

	}
	public int findTheRecordNumber(String s, int page) throws IOException{
		int record = -1;
		for(int i=0; i<2; i++){
			String tableName="";
			raf.seek(32+i*240);
			boolean recordIsNotAvailable =raf.readBoolean();
			if(!recordIsNotAvailable){
				raf.seek(32+i*240+page*512);
				for(int j=0; j<26; j++){
					tableName += (char) raf.readByte();
				}
				if(s.equals(tableName)){
					record = i;
				}
			}
		}
		return record;
	}
	public boolean isInTable(String s) throws IOException{
		int page = findPageNumber(s);
		if(page == -1){
			return false;
		}
		int record = findTheRecordNumber(s, page);
		if(record == -1){
			return false;
		}
		return true;
	}
	public boolean isInTable2(String s) throws IOException{
		byte[] temp = new byte[27];
		int pageNumber = pageNumber();
		for(int i=0; i<pageNumber; i++){
			int offset = i*256;
			raf.seek(offset);
			boolean status = raf.readBoolean();
			if(status){
				raf.seek(offset+1);
				raf.read(temp);
				String name = byteToString(temp);
				if(s.equals(name)){
					return true;
				}
			}
		}
		return false;
	}
	public ArrayList<Integer> firstAvailablePlace() throws IOException{
		ArrayList<Integer> result = new ArrayList<Integer>();
		int pageNumber = pageNumber();
		for(int i=0; i<pageNumber; i++){
			int offset = i*256;
			raf.seek(offset);
			boolean status = raf.readBoolean();
			if(!status){
				result.add(i/2);
				result.add(i%2);
				return result;
			}
		}
		result.add(-1);
		return result;
	}
	public void addTable(TableRecord record) throws IOException{
		int page = findPageNumber(record.getTableName());
		int pageNumber = pageNumber();
		if(page==-1){
			raf.seek((pageNumber-1)*512+31);
			int numberOfSpace = raf.read();
			if(numberOfSpace>0){
				//write the record
			}else{
				createAPage();
				//write the record
			}
		}else{
			
		}
		
	}
	public byte[] recordToByte(TableRecord record){
		byte[] recordInByte = new byte[240];
		recordInByte[0] = (byte) record.getStatus();
		System.arraycopy(stringToByte(record.getTableName()), 0, recordInByte, 1, record.getTableName().length());
		recordInByte[26] = (byte) record.getNumberOfFields();
		recordInByte[27] = (byte) record.getNumberOfTotalIndexRecord();
		recordInByte[28] = (byte) record.getSizeOfAnIndexRecord();
		recordInByte[29] = (byte) record.getNumberOfTotalDataRecord();
		recordInByte[30] = (byte) record.getSizeOfADataRecord();
		for(int i=0; i<record.getNumberOfFields(); i++){
			String temp = record.getFieldNames().get(i);
			System.arraycopy(stringToByte(temp), 0, recordInByte, 31+16*i, temp.length());
			recordInByte[46+16*i] = record.getFieldSizes().get(i).byteValue();
		}
		return recordInByte;
	}
	public byte[] stringToByte(String s){
		byte[] stringInByte = new byte[s.length()];
		for(int i=0; i<s.length(); i++){
			stringInByte[i] = (byte) s.charAt(i);
		}
		return stringInByte;
	}
	public String byteToString(byte[] b){
		String result = "";
		for(int i=0; i<b.length; i++){
			if(b[i] != 0){
				result += (char)b[i];
			}
		}
		return result;
	}
}
